﻿namespace Caltrain.Model
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using ProtoBuf;

    /// <summary>
    /// Model class
    /// </summary>
    public class ScheduleManager
    {
        private Schedule schedule;

        public void Initialize()
        {
            this.schedule = Serializer.Deserialize<Schedule>(Assembly.GetExecutingAssembly().GetManifestResourceStream("Caltrain.schedule"));
        }

        public List<string> GetStations()
        {
            return this.schedule.StopsById.Keys.ToList();
        }

        public List<KeyValuePair<StopTime, StopTime>> GetSchedule(
            string startStation,
            string endStation,
            DateTime date)
        {
            Dictionary<string, Service> servicesForDate = new Dictionary<string, Service>();
            foreach (Service service in schedule.Calendar.Services)
            {
                // TODO: Enddate comparison must account for time
                if (service.Days[date.DayOfWeek] &&
                    date >= service.StartDate &&
                    date <= service.EndDate)
                {
                    servicesForDate.Add(service.Id, service);
                }
            }

            int startStationId = schedule.StopsById[startStation].LookupId;
            int endStationid = schedule.StopsById[endStation].LookupId;

            List<StopTime> startTimings = schedule.StopTimesByStopId[startStationId];
            List<StopTime> stopTimings = schedule.StopTimesByStopId[endStationid];

            List<KeyValuePair<StopTime, StopTime>> validTrips = new List<KeyValuePair<StopTime, StopTime>>();
            foreach (var startTime in startTimings)
            {
                var filteredStopTimings = stopTimings.Where((t) => t.TripLookupId == startTime.TripLookupId &&
                                                                   t.Sequence > startTime.Sequence &&
                                                                   servicesForDate.ContainsKey(schedule.TripsByLookupId[t.TripLookupId].ServiceId));
                foreach (var stopTime in filteredStopTimings)
                {
                    validTrips.Add(new KeyValuePair<StopTime, StopTime>(startTime, stopTime));
                }
            }

            validTrips.Sort((x, y) => x.Key.DepartureTime.CompareTo(y.Key.DepartureTime));

            return validTrips;
        }
    }
}
